package com.cx.utils;

import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.time.FastDateFormat;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class JSONParseUtil {

    public static int parse(Integer value) {
        return value == null ? 0 : value;
    }

    public static long parse(Long value) {
        return value == null ? 0 : value;
    }

    public static double parse(Double value) {
        return value == null ? 0 : value;
    }

    public static boolean parse(Boolean value) {
        return value == null ? false : value;
    }

    public static BigDecimal parse(BigDecimal value) {
        return value == null ? BigDecimal.ZERO : value;
    }

    public static String jsonSerial(Object value) {
        // 优先判断性能较高
        if (value == null) {
            return null;

        } else if (value instanceof Boolean) {
            return value.toString();

        } else if (value instanceof Character) {
            return value.toString();

        } else if (value instanceof Short) {
            return value.toString();

        } else if (value instanceof Integer) {
            return value.toString();

        } else if (value instanceof Long) {
            return String.valueOf(value);

        } else if (value instanceof Float) {
            return value.toString();

        } else if (value instanceof Double) {
            return value.toString();

        } else if (value instanceof Byte) {
            return value.toString();

        } else if (value instanceof String) {
            return value.toString();

        } else if (value instanceof BigDecimal) {
            return ((BigDecimal) value).toPlainString();

        } else if (value instanceof Date) {
            return FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.S").format(value);

        }

        return new String(ProtoStuffUtil.serialize(value));
    }


    @SuppressWarnings({"unchecked"})
    public static <T> T toObject(String value, Class<T> clazz) {
        if (value == null) {
            return null;
        } else if (clazz == Date.class) {
            DateConverter dateConverter = new DateConverter(null);
            String[] parsePatterns = {
                    "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.S", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH",
                    "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH", "yyyy/MM",
                    "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH", "yyyy.MM", "yyyy",
                    "yyyy年MM月dd日", "yyyy年MM月dd日 HH时mm分ss秒", "yyyy年MM月dd日 HH时mm分", "yyyy年MM月dd日 HH时", "yyyy年MM月"
            };
            dateConverter.setPatterns(parsePatterns);
            dateConverter.setLocale(Locale.CHINA);
            dateConverter.setTimeZone(TimeZone.getDefault());
            return dateConverter.convert(clazz, value);
        } else if (clazz == Boolean.class) {
            return (T) Boolean.valueOf(value);

        } else if (clazz == Character.class) {
            return (T) CharUtils.toCharacterObject(value);

        } else if (clazz == Short.class) {
            return (T) Short.valueOf(value);

        } else if (clazz == Integer.class) {
            return (T) Integer.valueOf(value);

        } else if (clazz == Long.class) {
            return (T) Long.valueOf(value);

        } else if (clazz == Float.class) {
            return (T) Float.valueOf(value);

        } else if (clazz == Double.class) {
            return (T) Double.valueOf(value);

        } else if (clazz == Byte.class) {
            return (T) Byte.valueOf(value);

        } else if (clazz == String.class) {
            return (T) value;

        } else if (clazz == BigDecimal.class) {
            return (T) new BigDecimal(value);

        }

        return (T) ProtoStuffUtil.deserialize(value.getBytes(), clazz);
    }

}